
package org.argetr.resim;

import org.argetr.resim.ui.component.basic.ColorConvertCI;
import org.argetr.resim.ui.component.basic.HistogramCI;
import org.argetr.resim.ui.component.basic.HistogramEqualizeCI;
import org.argetr.resim.ui.component.basic.NegativeCI;
import org.argetr.resim.ui.component.basic.RescaleCI;
import org.argetr.resim.ui.component.basic.ThresholdCI;
import org.argetr.resim.ui.component.datasources.ConstInputCI;
import org.argetr.resim.ui.component.datasources.ImageInputCI;
import org.argetr.resim.ui.component.datasources.ImageViewerCI;
import org.argetr.resim.ui.component.filter.AverageCI;
import org.argetr.resim.ui.component.filter.ConvolutionCI;
import org.argetr.resim.ui.component.filter.EdgeCI;
import org.argetr.resim.ui.component.math.AbsoluteCI;
import org.argetr.resim.ui.component.math.AddCI;
import org.argetr.resim.ui.component.math.AndCI;
import org.argetr.resim.ui.component.math.ComplexMagnitudeCI;
import org.argetr.resim.ui.component.math.DFTCI;
import org.argetr.resim.ui.component.math.DivideCI;
import org.argetr.resim.ui.component.math.ExtremaCI;
import org.argetr.resim.ui.component.math.IDFTCI;
import org.argetr.resim.ui.component.math.LogCI;
import org.argetr.resim.ui.component.math.MultiplyCI;
import org.argetr.resim.ui.component.math.NotCI;
import org.argetr.resim.ui.component.math.OrCI;
import org.argetr.resim.ui.component.math.PowerCI;
import org.argetr.resim.ui.component.math.SubtractCI;
import org.argetr.resim.ui.component.math.XorCI;
import org.argetr.resim.ui.component.view.ViewerCI;
import org.argetr.resim.ui.model.ComponentItem;
import org.argetr.resim.ui.model.Connection;
import org.eclipse.gef.palette.CombinedTemplateCreationEntry;
import org.eclipse.gef.palette.ConnectionCreationToolEntry;
import org.eclipse.gef.palette.MarqueeToolEntry;
import org.eclipse.gef.palette.PaletteContainer;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.palette.PaletteGroup;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.palette.PaletteSeparator;
import org.eclipse.gef.palette.PanningSelectionToolEntry;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.gef.requests.SimpleFactory;
import org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;

/**
 * Utility class that can create a GEF Palette.
 * 
 * @see #createPalette()
 * @author Elias Volanakis
 */
final class ShapesEditorPaletteFactory {

	/** Preference ID used to persist the palette location. */
	private static final String PALETTE_DOCK_LOCATION = "ShapesEditorPaletteFactory.Location";
	/** Preference ID used to persist the palette size. */
	private static final String PALETTE_SIZE = "ShapesEditorPaletteFactory.Size";
	/** Preference ID used to persist the flyout palette's state. */
	private static final String PALETTE_STATE = "ShapesEditorPaletteFactory.State";

	/**
	 * Creates the PaletteRoot and adds all palette elements. Use this factory
	 * method to create a new palette for your graphical editor.
	 * 
	 * @return a new PaletteRoot
	 */
	static PaletteRoot createPalette() {
		PaletteRoot palette = new PaletteRoot();
		palette.setLabel("ToolBox");
		palette.add(createToolsGroup(palette));		
		ShapesEditorPaletteFactory.RegisterComponentsFromList(palette);
		return palette;
	}

	/**
	 * Return a FlyoutPreferences instance used to save/load the preferences of
	 * a flyout palette.
	 */
	static FlyoutPreferences createPalettePreferences() {
		return new FlyoutPreferences() {
			private IPreferenceStore getPreferenceStore() {
				return ShapesPlugin.getDefault().getPreferenceStore();
			}

			public int getDockLocation() {
				return getPreferenceStore().getInt(PALETTE_DOCK_LOCATION);
			}

			public int getPaletteState() {
				return getPreferenceStore().getInt(PALETTE_STATE);
			}

			public int getPaletteWidth() {
				return getPreferenceStore().getInt(PALETTE_SIZE);
			}

			public void setDockLocation(int location) {
				getPreferenceStore().setValue(PALETTE_DOCK_LOCATION, location);
			}

			public void setPaletteState(int state) {
				getPreferenceStore().setValue(PALETTE_STATE, state);
			}

			public void setPaletteWidth(int width) {
				getPreferenceStore().setValue(PALETTE_SIZE, width);
			}
		};
	}

	/** Create the "Tools" group. */
	private static PaletteContainer createToolsGroup(PaletteRoot palette) {
		PaletteGroup toolGroup = new PaletteGroup("Tools");

		// Add a selection tool to the group
		ToolEntry tool = new PanningSelectionToolEntry();
		toolGroup.add(tool);
		palette.setDefaultEntry(tool);

		// Add a marquee tool to the group
		toolGroup.add(new MarqueeToolEntry());

		// Add a (unnamed) separator to the group
		toolGroup.add(new PaletteSeparator());

		// Add (solid-line) connection tool
		tool = new ConnectionCreationToolEntry("Connection",
				"Create a connection", new CreationFactory() {
					public Object getNewObject() {
						return null;
					}

					// see ShapeEditPart#createEditPolicies()
					// this is abused to transmit the desired line style
					public Object getObjectType() {
						return Connection.SOLID_CONNECTION;
					}
				}, ImageDescriptor.createFromFile(ShapesPlugin.class,
						"icons/connection_s16.gif"), ImageDescriptor
						.createFromFile(ShapesPlugin.class,
								"icons/connection_s24.gif"));
		toolGroup.add(tool);

		return toolGroup;
	}

	/** Utility class. */
	private ShapesEditorPaletteFactory() {
		// Utility class
	}
	
	public static void RegisterComponentsFromList(PaletteRoot palette)
	{
		ImageInputCI imgInputCI = new ImageInputCI();	
		ComponentTree.AddComponentItem("Data Sources",imgInputCI);
		
	    ConstInputCI constInputCI = new ConstInputCI();	
		ComponentTree.AddComponentItem("Data Sources",constInputCI);
		
		//ImageViewerCI imgViewerCI = new ImageViewerCI();
		//ComponentTree.AddComponentItem("Viewers", imgViewerCI);
		
		ColorConvertCI colorConvertCI = new ColorConvertCI();
		ComponentTree.AddComponentItem("Basic", colorConvertCI);
		
		HistogramEqualizeCI histEqCI = new HistogramEqualizeCI();
		ComponentTree.AddComponentItem("Basic", histEqCI);
		
		NegativeCI negCI = new NegativeCI();
		ComponentTree.AddComponentItem("Basic", negCI);
		
		RescaleCI resCI = new RescaleCI();
		ComponentTree.AddComponentItem("Basic", resCI);
		
		ThresholdCI thresCI = new ThresholdCI();
		ComponentTree.AddComponentItem("Basic", thresCI);
		
		HistogramCI histCI = new HistogramCI();
		ComponentTree.AddComponentItem("Basic", histCI);
		
		ViewerCI viewerCI = new ViewerCI();
		ComponentTree.AddComponentItem("Basic", viewerCI);

		AddCI adderCI = new AddCI();
		ComponentTree.AddComponentItem("Math", adderCI);
		
		SubtractCI subCI = new SubtractCI();
		ComponentTree.AddComponentItem("Math", subCI);
		
		MultiplyCI mulCI = new MultiplyCI();
		ComponentTree.AddComponentItem("Math", mulCI);
		
		DivideCI divideCI = new DivideCI();
		ComponentTree.AddComponentItem("Math", divideCI);
		
		PowerCI powerCI = new PowerCI();
		ComponentTree.AddComponentItem("Math", powerCI);	
		
		LogCI logCI = new LogCI();
		ComponentTree.AddComponentItem("Math", logCI);
		
		ExtremaCI extCI = new ExtremaCI();
		ComponentTree.AddComponentItem("Math", extCI);
		
		AbsoluteCI absCI = new AbsoluteCI();
		ComponentTree.AddComponentItem("Math", absCI);
		
		ComplexMagnitudeCI compMagCI = new ComplexMagnitudeCI();
		ComponentTree.AddComponentItem("Math", compMagCI);
		
		DFTCI dftCI = new DFTCI();
		ComponentTree.AddComponentItem("Math", dftCI);
		
		IDFTCI idftCI = new IDFTCI();
		ComponentTree.AddComponentItem("Math", idftCI);
		
		AndCI andCI = new AndCI();
		ComponentTree.AddComponentItem("Logical", andCI);
		
		OrCI orCI = new OrCI();
		ComponentTree.AddComponentItem("Logical", orCI);
		
		XorCI xorCI = new XorCI();
		ComponentTree.AddComponentItem("Logical", xorCI);
		
		NotCI notCI = new NotCI();
		ComponentTree.AddComponentItem("Logical", notCI);
		
		EdgeCI edgeCI = new EdgeCI();
		ComponentTree.AddComponentItem("Filter", edgeCI);
		
		AverageCI averageCI = new AverageCI();
		ComponentTree.AddComponentItem("Filter", averageCI);
		
		ConvolutionCI convolutionCI = new ConvolutionCI();
		ComponentTree.AddComponentItem("Filter", convolutionCI);
//----------------------------------------------------------------------
		for(String groupName : ComponentTree.iterateGroups())
		{
			PaletteDrawer componentsDrawer = new PaletteDrawer(groupName);
			ComponentCollection compColl = ComponentTree.GetComponentCollectionByGroupName(groupName);
			for(ComponentItem compItem : compColl)
			{
				CombinedTemplateCreationEntry component = new CombinedTemplateCreationEntry(
						compItem.GetName(), compItem.GetDescription(), compItem.getComponentClass(),
						new SimpleFactory(compItem.getComponentClass()), ImageDescriptor
								.createFromFile(compItem.getComponentClass(),
										"icons/ellipse16.gif"), ImageDescriptor
								.createFromFile(compItem.getComponentClass(),
										"icons/ellipse24.gif"));
				componentsDrawer.add(component);
			}
			componentsDrawer.setInitialState(PaletteDrawer.INITIAL_STATE_CLOSED);
			palette.add(componentsDrawer);			
		}
	}
}